<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Input &amp; output in Ruby</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Ruby, learn Ruby, language, programming, Linux, scripting language, 
Input &amp; output, directories, files">
<meta name="description" content="In this part of the Ruby tutorial we work
with input &amp; output in Ruby.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<div class="content2">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Input &amp; output in Ruby</h1>

<p>
In this part of the Ruby tutorial, we will talk about Input &amp; output operations
in Ruby. The input is any data that is read by the program, either from a keyboard,
file or other programs. The output is data that is produced by the program. The
output may go to the screen, to a file or to another program. 
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
Input &amp; output is a large topic. We bring forward some examples to give you a 
general idea of the subject. Several classes in Ruby have methods for doing input/output
operations. For example <code>Kernel</code>, <code>IO</code>, 
<code>Dir</code> or <code>File</code>.
</p>


<h2>Writing to console</h2>

<p>
Ruby has several methods for printing output on the console. These
methods are part of the <code>Kernel</code> module. Methods of the
<code>Kernel</code> are available to all objects in Ruby. 
</p>

<pre class="code">
#!/usr/bin/ruby

print "Apple "
print "Apple\n"

puts "Orange"
puts "Orange"
</pre>

<p> 
The <code>print</code> and <code>puts</code> methods produce textual output
on the console. The difference between the two is that the latter adds
a new line character. 
</p>

<pre class="explanation">
print "Apple "
print "Apple\n"
</pre>

<p>
The print method prints two consecutive "Apple" strings to the terminal. 
If we want to create a new line, we must explicitly include the newline character.
The newline character is '\n'. Behind the scenes. the <code>print</code> method
actually calls the <code>to_s</code> method of the object being printed. 
</p>

<pre class="explanation">
puts "Orange"
puts "Orange"
</pre>

<p>
The <code>puts</code> method prints two strings to the console. They are on a separate
line. The method includes automatically the newline character. 
</p>


<pre>
$ ./printing.rb
Apple Apple
Orange
Orange
</pre>

<p>
Output of the printing.rb script file. 
</p>

<hr class="btm">

<p>
According to the Ruby documentation, the <code>print</code> method is an
equivalent to the <code>$stdout.print</code>. The <code>$stdout</code> is
a global variable which holds the standard output stream. 
</p>

<pre class="code">
#!/usr/bin/ruby

$stdout.print "Ruby language\n"
$stdout.puts "Python language"
</pre>

<p>
We print two lines using the <code>$stdout</code> variable. 
</p>

<hr class="btm">

<p>
Ruby has another three methods for printing output.
</p>

<pre class="code">
#!/usr/bin/ruby

p "Lemon"
p "Lemon"

printf "There are %d apples\n", 3

putc 'K'
putc 0xA
</pre>

<p>
In the example, we present <code>p</code>, <code>printf</code> and
<code>putc</code> methods. 
</p>

<pre class="explanation">
p "Lemon"
</pre>

<p>
The <code>p</code> calls the <code>inspect</code> method upon the 
object being printed. The method is useful for debugging. 
</p>

<pre class="explanation">
printf "There are %d apples\n", 3
</pre>

<p>
The <code>printf</code> method is well known from the C programming language.
It enables string formatting. 
</p>

<pre class="explanation">
putc 'K'
putc 0xA
</pre>

<p>
The <code>putc</code> method prints one character to the console. The second
line prints a newline. The 0xA is a hexadecimal code for the newline character.
</p>

<pre>
$ ./printing3.rb 
"Lemon"
"Lemon"
There are 3 apples
K
</pre>

<p>
Output of the example.
</p>

<hr class="btm">

<p>
Printing data to the console using the 
kernel methods is a shortcut. A convenient way to 
print data. The following example shows a more formal
way to print data to the terminal.
</p>

<pre class="code">
ios = IO.new STDOUT.fileno
ios.write "ZetCode\n"
ios.close
</pre>

<p>
In the example, we open a standard output stream and write
a string into it.
</p>

<pre class="explanation">
ios = IO.new STDOUT.fileno
</pre>

<p>
The <code>new</code> method returns a stream to which we can
write data. The method takes a numeric file descriptor. 
The <code>STDOUT.fileno</code> gives us the file descriptor for
the standard output stream. We could also simply write 2.
</p>

<pre class="explanation">
ios.write "ZetCode\n"
</pre>

<p>
We write a string to the opened stream. 
</p>

<pre class="explanation">
ios.close
</pre>

<p>
The input stream is closed. 
</p>


<hr class="btm">

<p>
On Unix systems the standard terminal output is connected to a special file
called /dev/tty. By opening it and writing to it, we write to a console.
</p>

<pre class="code">
#!/usr/bin/ruby

fd = IO.sysopen "/dev/tty", "w"
ios = IO.new(fd, "w")
ios.puts "ZetCode"
ios.close
</pre>

<p>
A small example in which we write to a /dev/tty file. This only works on Unix.
</p>

<pre class="explanation">
fd = IO.sysopen "/dev/tty", "w"
</pre>

<p>
The <code>sysopen</code> method opens the given path, 
returning the underlying file descriptor number.
</p>

<pre class="explanation">
ios = IO.new(fd, "w")
</pre>

<p>
The file descriptor number is used to open a stream. 
</p>


<pre class="explanation">
ios.puts "ZetCode"
ios.close
</pre>

<p>
We write a string to the stream and close it. 
</p>


<h2>Reading input from console</h2>

<p>
In this section, we will create some code examples that
will deal with reading from the console. 
</p>

<p>
The <code>$stdin</code> is a global variable that holds a stream
for the standard input. It can be used to read input from the console.
</p>

<pre class="code">
#!/usr/bin/ruby
 
inp = $stdin.read
puts inp
</pre>

<p>
In the above code, we use the <code>read</code> method to read input
from the console.
</p>

<pre class="explanation">
inp = $stdin.read
</pre>

<p>
The <code>read</code> method reads data from the standard input, until
it reaches the end of the file. The EOF is produced by pressing Ctrl + D on
Unix or Ctrl + Z on Windows. 
</p>

<pre>
$ ./reading.rb
Ruby language
Ruby language
</pre>

<p>
When we launch a program without a parameter, the script reads data from the
user. It reads until we press Ctrl + D or Ctrl + Z. 
</p>

<pre>
$ echo "ZetCode" | ./reading.rb
ZetCode

$ ./input.rb &lt; stones 
Garnet
Topaz
Opal
Amethyst
Ruby
Jasper
Pyrite
Malachite
Quartz
</pre>

<p>
The script can read data from another program or a file, if we do 
some redirections.
</p>

<hr class="btm">

<p>
The common way to read data from the console is to use the <code>gets</code> 
method. 
</p>

<pre class="code">
#!/usr/bin/ruby

print "Enter your name: "
name = gets
puts "Hello #{name}"
</pre>

<p> 
We use the <code>gets</code> method to read a line from the user.
</p>

<pre class="explanation">
name = gets
</pre>

<p>
The <code>gets</code> method reads a line from the standard input. 
The data is assigned to the name variable. 
</p>

<pre class="explanation">
puts "Hello #{name}"
</pre>

<p>
The data that we have read is printed to the console. We use interpolation
to include the variable in the string. 
</p>

<pre>
$ ./readline.rb
Enter your name: Jan
Hello Jan
</pre>

<p>
Sample output.
</p>


<hr class="btm">

<p>
In the following two scripts, we will discuss the <code>chomp</code>
method. It is a string method. It removes white spaces from the
end of the string, if present. It is useful when doing input operations.
The method name and usage comes from the Perl language.
</p>

<pre class="code">
#!/usr/bin/ruby

print "Enter a string: "
inp = gets

puts "The string has #{inp.size} characters"
</pre>

<p>
We read a string from a user and calculate the length of the input string. 
</p>

<pre>
$ ./nochomp.rb 
Enter a string: Ruby
The string has 5 characters
</pre>

<p>
The message says that the string has 5 characters. It is because it counts
the newline as well. 
</p>

<hr class="btm">

<p>
To get the correct answer, we need to remove the newline
character. This is a job for the <code>chomp</code> method.
</p>

<pre class="code">
#!/usr/bin/ruby

print "Enter a string: "
inp = gets.chomp

puts "The string has #{inp.size} characters"
</pre>

<p>
This time we use we cut the newline character with the <code>chomp</code>
method. 
</p>

<pre>
$ ./chomp.rb 
Enter a string: Ruby
The string has 4 characters
</pre>

<p>
The Ruby string has indeed 4 characters. 
</p>



<h2>Files</h2>

<p>
From the official Ruby documentation we learn that the <code>IO</code> class 
is the basis for all input and output in Ruby. The <code>File</code> class is
the only subclass of the <code>IO</code> class. The two classes are
closely related. 
</p>


<pre class="code">
#!/usr/bin/ruby

f = File.open('output.txt', 'w')
f.puts "The Ruby tutorial"
f.close
</pre>

<p>
In the first example, we open a file and
write some data to it. 
</p>

<pre class="explanation">
f = File.open('output.txt', 'w')
</pre>

<p>
We open a file 'output.txt' in a write mode. 
The <code>open</code> method returns an io
stream. 
</p>

<pre class="explanation">
f.puts "The Ruby tutorial"
</pre>

<p>
We used the above opened stream to write some data. 
The <code>puts</code> method can be used to write data
to a file as well. 
</p>

<pre class="explanation">
f.close
</pre>

<p>
At the end the stream is closed. 
</p>

<pre>
$ ./simplewrite.rb
$ cat output.txt 
The Ruby tutorial
</pre>

<p>
We execute the script and show the contents of
the output.txt file. 
</p>

<hr class="btm">

<p>
We will have a similar example, which will show additional
methods in action.
</p>

<pre class="code">
#!/usr/bin/ruby

File.open('langs', 'w') do |f|
   
    f.puts "Ruby"
    f.write "Java\n"
    f &lt;&lt; "Python\n"
    
end
</pre>

<p>
If there is a block after the <code>open</code> method,
then Ruby passes the opened stream to this block. At the
end of the block, the file is automatically closed. 
</p>

<pre class="explanation">
f.puts "Ruby"
f.write "Java\n"
f &lt;&lt; "Python\n"
</pre>

<p>
We use three different methods to write to a file. 
</p>

<pre>
$ ./simplewrite2.rb
$ cat langs 
Ruby
Java
Python
</pre>

<p>
We execute the script and check the contents of the langs file. 
</p>

<hr class="btm">

<p>
In the second example, we show a few methods of the 
<code>File</code> class. 
</p>

<pre class="code">
#!/usr/bin/ruby

puts File.exists? 'tempfile'

f = File.new 'tempfile', 'w'
puts File.mtime 'tempfile'
puts f.size

File.rename 'tempfile', 'tempfile2'

f.close
</pre>

<p>
The example creates a new file named 'tempfile' and calls
some methods. 
</p>

<pre class="explanation">
puts File.exists? 'tempfile'
</pre>

<p>
The <code>exists?</code> method checks, if a file with a
given name already exists. The line returns false, because we have
not yet created the file.
</p>

<pre class="explanation">
f = File.new 'tempfile', 'w'
</pre>

<p>
The file is created. 
</p>

<pre class="explanation">
puts File.mtime 'tempfile'
</pre>

<p>
The <code>mtime</code> method gives us the last modification time
of the file. 
</p>

<pre class="explanation">
puts f.size
</pre>

<p>
We determine the file size. The method returns 0, since we have not
written to the file. 
</p>

<pre class="explanation">
File.rename 'tempfile', 'tempfile2'
</pre>

<p>
Finally, we rename the file using the <code>rename</code> method.
</p>

<pre>
$ ./testfile.rb
false
2011-11-05 16:19:36 +0100
0
</pre>

<p>
Sample output.
</p>

<hr class="btm">

<p>
Next, we will be reading data from the files on the disk.  
</p>

<pre class="code">
#!/usr/bin/ruby

f = File.open("stones")

while line = f.gets do
    puts line
end

f.close
</pre>

<p>
This is a simple script, that will open a file called stones and
print it contents line by line to the terminal. 
</p>

<pre class="explanation">
f = File.open("stones")
</pre>

<p>
We open a 'stones' file. The default  mode is a read mode. 
The 'stones' file contains nine names of valued stones; each
on a separate line. 
</p>

<pre class="explanation">
while line = f.gets do
    puts line
end
</pre>

<p>
The <code>gets</code> method reads a line from the I/O stream.
The while block ends when we reach the end of file. 
</p>

<pre>
$ ./readlines2.rb
Garnet
Topaz
Opal
Amethyst
Ruby
Jasper
Pyrite
Malachite
Quartz
</pre>

<p>
Output of the example.
</p>

<hr class="btm">

<p>
The next example will read data from a file.
</p>

<pre class="code">
#!/usr/bin/ruby

fname = 'alllines.rb'

File.readlines(fname).each do |line|
    puts line
end
</pre>

<p>
This script is another way, how we can read contents
of a file. The code example will print its own code
to the terminal. 
</p>

<pre class="explanation">
File.readlines(fname).each do |line|
    puts line
end
</pre>

<p>
The <code>readlines</code> reads all lines from the specified
file and returns them in the form of an array. We go through
the array with the <code>each</code> method and print the lines
to the terminal. 
</p>

<pre>
$ ./alllines.rb
#!/usr/bin/ruby

fname = 'alllines.rb'

File.readlines(fname).each do |line|
    puts line
end
</pre>

<p>
Output of the example. 
</p>


<h2>Directories</h2>

<p>
In this section, we work with directories. We have a <code>Dir</code> class
to work with directories in Ruby. 
</p>


<pre class="code">
#!/usr/bin/ruby

Dir.mkdir "tmp"
puts Dir.exists? "tmp"

puts Dir.pwd
Dir.chdir "tmp"
puts Dir.pwd

Dir.chdir '..'
puts Dir.pwd
Dir.rmdir "tmp"
puts Dir.exists? "tmp"
</pre>

<p>
In the script we use four methods of the <code>Dir</code> class. 
</p>

<pre class="explanation">
Dir.mkdir "tmp"
</pre>

<p>
The <code>mkdir</code> method makes a new directory called 'tmp'. 
</p>

<pre class="explanation">
puts Dir.exists? "tmp"
</pre>

<p>
With the <code>exists?</code> method, we check if
a directory with a given name exists in the filesystem. 
</p>

<pre class="explanation">
puts Dir.pwd
</pre>

<p>
The <code>pwd</code> method prints a current working directory.
It is a directory, where we have launched the script.
</p>

<pre class="explanation">
Dir.chdir '..'
</pre>

<p>
The <code>chdir</code> method changes to another directory. The '..'
directory is the parent directory of the current working directory. 
</p>

<pre class="explanation">
Dir.rmdir "tmp"
puts Dir.exists? "tmp"
</pre>

<p>
Finally, we remove a directory with the <code>rmdir</code> method.
This time the <code>exists?</code> method returns false. 
</p>

<pre>
$ ./dirs.rb
true
/home/vronskij/programming/ruby/io
/home/vronskij/programming/ruby/io/tmp
/home/vronskij/programming/ruby/io
false
</pre>

<p>
Output of the example. 
</p>

<hr class="btm">

<p>
In the second example, we retrieve all entries of a directory.
Both files and directories.
</p>

<pre class="code">
#!/usr/bin/ruby

fls = Dir.entries '.'
puts fls.inspect
</pre>

<p>
The <code>entries</code> method returns all entries of 
a given diretory. 
</p>

<pre class="explanation">
fls = Dir.entries '.'
puts fls.inspect
</pre>

<p>
We get the array of files and directories of a current directory. 
The '.' character stands for the current working directory in this 
constext. The <code>inspect</code> method gives us a more readable 
representation of the array. 
</p>

<pre>
$ ./allfiles.rb
["putc.rb", "simplewrite.rb", "readlines2.rb", "fileexists.rb~" ...
</pre>

<p>
In the output we can see an array of files and directories. 
</p>

<hr class="btm">

<p>
The third example works with a home directory. Every user in a computer
has a unique directory assigned to him. It is called a home directory. 
It is a place where he can place his files and create his own hierarchy
of directories. 
</p>

<pre class="code">
#!/usr/bin/ruby

puts Dir.home
puts Dir.home 'root'
</pre>

<p>
The script prints two home directories. 
</p>

<pre class="explanation">
puts Dir.home
</pre>

<p>
If we do not specify the user name, then a home directory of a current
user is returned. The current user is the owner of the script file. Someone,
who has launched the script. 
</p>

<pre class="explanation">
puts Dir.home 'root'
</pre>

<p>
Here we print the home directory of a specific user. In our case the superuser. 
</p>

<pre>
$ ./homedir.rb
/home/vronskij
/root
</pre>

<p>
Sample output. 
</p>


<h2>Executing external programs</h2>

<p>
Ruby has several ways to execute external programs. 
We will deal with some of them. In our examples we will use
well known Linux commands. Readers with Windows or Mac can
use commands specific for their systems. 
</p>

<pre class="code">
#!/usr/bin/ruby

data = system 'ls'
puts data
</pre>

<p>
We call a <code>ls</code> command, which lists directory contents.
</p>

<pre class="explanation">
data = system 'ls'
</pre>

<p>
The <code>system</code> command executes an external program in a subshell. The method
belongs to the <code>Kernel</code> Ruby module. 
</p>

<pre>
$ ./system.rb
allfiles.rb   characters.rb  fileexists.rb   homedir.rb~ ...
</pre>

<p>
A sample output. 
</p>

<hr class="btm">

<p>
We show another two ways of running external programs in Ruby.
</p>

<pre class="code">
#!/usr/bin/ruby

out = `pwd`
puts out

out = %x[uptime]
puts out

out = %x[ls | grep 'readline']
puts out
</pre>

<p>
To run external programs we can use backticks `` or %x[] characters.
</p>

<pre class="explanation">
out = `pwd`
</pre>

<p>
Here we execute the <code>pwd</code> command using backticks. The
command returns the current working directory. 
</p>

<pre class="explanation">
out = %x[uptime]
</pre>

<p>
Here we get the output of the <code>uptime</code> command, which 
tells how long a system is running. 
</p>

<pre class="explanation">
out = %x[ls | grep 'readline']
</pre>

<p>
We can use also a combination of commands. 
</p>

<pre>
$ ./system2.rb
/home/vronskij/programming/ruby/io
 22:50:50 up  5:32,  1 user,  load average: 0.46, 0.44, 0.45
readline.rb
readline.rb~
readlines2.rb
readlines2.rb~
</pre>

<p>
Sample output.
</p>

<hr class="btm">

<p>
We can execute a command with the <code>open</code> method.
The method belongs to the <code>Kernel</code> module. It
creates an IO object connected to the given stream, 
file, or subprocess. If we want to connect to a subprocess,
we start the path of the <code>open</code> with a pipe character (|).
</p>

<pre class="code">
#!/usr/bin/ruby

f = open("|ls -l |head -3")
out = f.read
puts out
f.close

puts $?.success?
</pre>

<p>
In the example, we print the outcome of the <code>ls -l | head -3</code>
commands. The combination of these two commands return the first three lines
of the <code>ls -l</code> command. We also check the status of the 
child subprocess.
</p>

<pre class="explanation">
f = open("|ls -l |head -3")
</pre>

<p>
We connect to a subprocess, created by these two commands. 
</p>

<pre class="explanation">
out = f.read
puts out
</pre>

<p>
We read and print data from the subprocess. 
</p>

<pre class="explanation">
f.close
</pre>

<p>
We close the file handler. 
</p>

<pre class="explanation">
puts $?.success?
</pre>

<p>
The <code>$?</code> is a special Ruby variable, which obtains
the status of the last executed child process. The <code>success?</code>
method returns true, if the child process ended OK, false otherwise. 
</p>

<pre>
$ ./system3.rb
total 148
-rwxr-xr-x 1 vronskij vronskij   57 2011-10-30 23:33 allfiles.rb
-rwxr-xr-x 1 vronskij vronskij   58 2011-10-30 23:33 allfiles.rb~
true
</pre>

<p>
Sample output.
</p>


<h2>Redirecting standard output</h2>

<p>
Ruby has predefined global variables for standard input, standard output
and standard error output. The <code>$stdout</code> is the name of the
variable for the standard output. 
</p>

<pre class="code">
#!/usr/bin/ruby

$stdout = File.open "output.log", "a"

puts "Ruby"
puts "Java"

$stdout.close
$stdout = STDOUT

puts "Python"
</pre>

<p>
In the above example, we redirect a standard output to the output.log file. 
</p>

<pre class="explanation">
$stdout = File.open "output.log", "a"
</pre>

<p>
This line creates a new standard ouput. The standard output will now
flow to the ouput.log file. The file is opened in an append mode. If the file
does not exist yet, it is created. Otherwise it is opened and the data is 
written at the end of the file. 
</p>

<pre class="explanation">
puts "Ruby"
puts "Java"
</pre>

<p>
We print two strings. The strings will not be shown in the terminal as usual,
they will be appended to the output.log file. 
</p>

<pre class="explanation">
$stdout.close
</pre>

<p>
We close the handler. 
</p>

<pre class="explanation">
$stdout = STDOUT

puts "Python"
</pre>

<p>
We use a predefined standard constant <code>STDOUT</code> to recreate the
normal standard ouput. The "Python" string is printed to a console. 
</p>


<p>
In this part of the Ruby tutorial, we worked with input and output operations
in Ruby.
</p>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified December 15, 2011  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
